package com.approval.service;

import com.approval.dto.*;
import com.approval.entity.*;
import com.approval.exception.BusinessException;
import com.approval.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 授权管理服务
 */
@Service
@Transactional
public class AuthService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    /**
     * 为用户分配角色
     */
    public void assignRolesToUser(UserRoleAssignRequest request) {
        // 删除现有角色
        userRoleMapper.deleteByUserId(request.getUserId());
        
        // 分配新角色
        if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
            for (Long roleId : request.getRoleIds()) {
                Role role = roleMapper.selectById(roleId);
                if (role == null) {
                    throw new BusinessException("角色不存在: " + roleId);
                }
                
                UserRole userRole = new UserRole();
                userRole.setUserId(request.getUserId());
                userRole.setRoleId(roleId);
                userRole.setCreateTime(new Date());
                userRoleMapper.insert(userRole);
            }
        }
    }
    
    /**
     * 为角色分配权限
     */
    public void assignPermissionsToRole(RolePermissionAssignRequest request) {
        // 删除现有权限
        rolePermissionMapper.deleteByRoleId(request.getRoleId());
        
        // 分配新权限
        if (request.getPermissionIds() != null && !request.getPermissionIds().isEmpty()) {
            for (Long permissionId : request.getPermissionIds()) {
                Permission permission = permissionMapper.selectById(permissionId);
                if (permission == null) {
                    throw new BusinessException("权限不存在: " + permissionId);
                }
                
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(request.getRoleId());
                rolePermission.setPermissionId(permissionId);
                rolePermission.setCreateTime(new Date());
                rolePermissionMapper.insert(rolePermission);
            }
        }
    }
    
    /**
     * 获取用户权限预览
     */
    public UserPermissionPreviewResponse getUserPermissionPreview(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        List<Permission> allPermissions = permissionMapper.selectByUserId(userId);
        
        List<PermissionResponse> menuPermissions = allPermissions.stream()
            .filter(p -> "menu".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> operationPermissions = allPermissions.stream()
            .filter(p -> "operation".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> dataPermissions = allPermissions.stream()
            .filter(p -> "data".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<String> allPermissionCodes = allPermissions.stream()
            .map(Permission::getPermissionCode)
            .collect(Collectors.toList());
        
        UserPermissionPreviewResponse response = new UserPermissionPreviewResponse();
        response.setUserId(user.getId());
        response.setUsername(user.getUsername());
        response.setName(user.getName());
        response.setRoles(roleMapper.selectByUserId(userId).stream().map(this::convertToRoleResponse).collect(Collectors.toList()));
        response.setMenuPermissions(menuPermissions);
        response.setOperationPermissions(operationPermissions);
        response.setDataPermissions(dataPermissions);
        response.setAllPermissions(allPermissionCodes);
        
        return response;
    }
    
    /**
     * 获取角色权限预览
     */
    public RolePermissionPreviewResponse getRolePermissionPreview(Long roleId) {
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        List<Permission> allPermissions = permissionMapper.selectByRoleId(roleId);
        
        List<PermissionResponse> menuPermissions = allPermissions.stream()
            .filter(p -> "menu".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> operationPermissions = allPermissions.stream()
            .filter(p -> "operation".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<PermissionResponse> dataPermissions = allPermissions.stream()
            .filter(p -> "data".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
        
        List<String> allPermissionCodes = allPermissions.stream()
            .map(Permission::getPermissionCode)
            .collect(Collectors.toList());
        
        RolePermissionPreviewResponse response = new RolePermissionPreviewResponse();
        response.setRoleId(role.getId());
        response.setRoleName(role.getRoleName());
        response.setRoleCode(role.getRoleCode());
        response.setUserCount(userRoleMapper.countByRoleId(roleId));
        response.setMenuPermissions(menuPermissions);
        response.setOperationPermissions(operationPermissions);
        response.setDataPermissions(dataPermissions);
        response.setAllPermissions(allPermissionCodes);
        
        return response;
    }
    
    /**
     * 检查用户是否有指定权限
     */
    public boolean hasPermission(Long userId, String permissionCode) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream()
            .anyMatch(p -> permissionCode.equals(p.getPermissionCode()));
    }
    
    /**
     * 检查用户是否有指定资源和操作的权限
     */
    public boolean hasPermission(Long userId, String resource, String operation) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream()
            .anyMatch(p -> resource.equals(p.getResource()) && operation.equals(p.getOperation()));
    }
    
    /**
     * 获取用户的所有权限编码
     */
    public List<String> getUserPermissionCodes(Long userId) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream()
            .map(Permission::getPermissionCode)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取用户的菜单权限
     */
    public List<PermissionResponse> getUserMenuPermissions(Long userId) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream()
            .filter(p -> "menu".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取用户的操作权限
     */
    public List<PermissionResponse> getUserOperationPermissions(Long userId) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return permissions.stream()
            .filter(p -> "operation".equals(p.getPermissionType()))
            .map(this::convertToPermissionResponse)
            .collect(Collectors.toList());
    }
    
    // 私有方法
    
    private RoleResponse convertToRoleResponse(Role role) {
        RoleResponse response = new RoleResponse();
        response.setId(role.getId());
        response.setRoleName(role.getRoleName());
        response.setRoleCode(role.getRoleCode());
        response.setRoleType(role.getRoleType());
        response.setDescription(role.getDescription());
        response.setStatus(role.getStatus());
        response.setParentId(role.getParentId());

        response.setSortOrder(role.getSortOrder());
        response.setCreateTime(role.getCreateTime());
        response.setUpdateTime(role.getUpdateTime());
        
        // 设置父角色名称
        if (role.getParentId() != null) {
            Role parentRole = roleMapper.selectById(role.getParentId());
            if (parentRole != null) {
                response.setParentRoleName(parentRole.getRoleName());
            }
        }
        
        // 设置用户数量
        response.setUserCount(userRoleMapper.countByRoleId(role.getId()));
        
        return response;
    }
    
    private PermissionResponse convertToPermissionResponse(Permission permission) {
        PermissionResponse response = new PermissionResponse();
        response.setId(permission.getId());
        response.setPermissionName(permission.getPermissionName());
        response.setPermissionCode(permission.getPermissionCode());
        response.setPermissionType(permission.getPermissionType());
        response.setResource(permission.getResource());
        response.setOperation(permission.getOperation());
        response.setDescription(permission.getDescription());
        response.setParentId(permission.getParentId());
        response.setSortOrder(permission.getSortOrder());
        response.setIcon(permission.getIcon());
        response.setPath(permission.getPath());
        response.setComponent(permission.getComponent());
        response.setStatus(permission.getStatus());
        response.setCreateTime(permission.getCreateTime());
        response.setUpdateTime(permission.getUpdateTime());
        
        // 设置父权限名称
        if (permission.getParentId() != null) {
            Permission parentPermission = permissionMapper.selectById(permission.getParentId());
            if (parentPermission != null) {
                response.setParentPermissionName(parentPermission.getPermissionName());
            }
        }
        
        // 设置角色数量
        response.setRoleCount(rolePermissionMapper.countByPermissionId(permission.getId()));
        
        return response;
    }
}